#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/types.h>
#include <asm/uaccess.h>

#define DEV_MAJOR 179
#define DEV_SIZE 100

static char dev_buf[DEV_SIZE] = "default values\n";

static int mydev_open(struct inode *inode, struct file *file)
{
	return 0;
}


static int mydev_release(struct inode *inode, struct file *file)
{
	return 0;
}

static int mydev_read(struct file *fp, char __user *buf, size_t len, loff_t *pos)
{
	unsigned long count = len;

	if (count > DEV_SIZE) {
		return -1;
	}

	if (copy_to_user(buf, dev_buf, len) != 0) {
		return -1;	
	}
	return 0;
}

static int mydev_write(struct file *fp, char __user *buf, size_t len, loff_t *pos)
{
	unsigned long count = len;
	if (count > DEV_SIZE) {
		return -1;
	}

	if (copy_from_user(dev_buf, buf, len) != 0) {
		return -1;
	}
	return 0;
}

static struct file_operations mydev_ops = {
	.owner = THIS_MODULE,
	.open = mydev_open,
	.release = mydev_release,
	.read = mydev_read,
	.write = mydev_write,
};

static int __init mydev_init(void)
{
	printk("I'm cdev driver, I'm coming\n");

	if (register_chrdev(DEV_MAJOR, "mydev", &mydev_ops) < 0) {
		return -1;
	}

	return 0;
}

static void __exit mydev_exit(void)
{
	printk("Bye\n");
	unregister_chrdev(DEV_MAJOR, "mydev");
}


MODULE_LICENSE("GPL");
module_init(mydev_init);
module_exit(mydev_exit);
